package ms.unicorn.erml.helper;

import java.util.Map;

import ms.unicorn.Element;
import ms.unicorn.erml.ERML;
import ms.unicorn.erml.edit.parts.ActorCompartmentEditPart;
import ms.unicorn.erml.edit.parts.ActorEditPart;
import ms.unicorn.erml.edit.parts.ContainerEntityEditPart;
import ms.unicorn.erml.figures.ActorCompartmentPaneFigure;
import ms.unicorn.erml.styles.ErmlStyle.CollapsableConstraint;
import ms.unicorn.erml.styles.ErmlStyle.ErmlStyleFactory;
import ms.unicorn.modellanguage.LanguageElement;
import ms.unicorn.modellanguage.LanguageEntityEditHeperAdvice;
import ms.unicorn.modellanguage.LanguageRelation;
import ms.unicorn.ui.figures.EntityOvalFigure;
import ms.unicorn.ui.layout.DockConstraint;
import ms.unicorn.ui.layout.DotNetLayout;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.EditPart;
import org.eclipse.gmf.runtime.diagram.core.preferences.PreferencesHint;
import org.eclipse.gmf.runtime.diagram.core.util.ViewUtil;
import org.eclipse.gmf.runtime.draw2d.ui.figures.WrappingLabel;
import org.eclipse.gmf.runtime.notation.BasicCompartment;
import org.eclipse.gmf.runtime.notation.NotationFactory;
import org.eclipse.gmf.runtime.notation.Size;
import org.eclipse.gmf.runtime.notation.View;

public class ActorEditHelperAdvice extends LanguageEntityEditHeperAdvice {

	public ActorEditHelperAdvice() {
		editPartMap.put(ENTITY_ID, ActorEditPart.class);
		editPartMap.put(ERML.ACTOR_COMPARTMENT_ID, ActorCompartmentEditPart.class);
	}
	
	@Override
	public boolean acceptChildren(LanguageElement element) {
		return element.equals(ERML.Requirement) ||
				element.equals(ERML.CompositionHub) ||
				element instanceof LanguageRelation;
	}

	@Override
	protected IFigure createFigureElement(Element element,
			String figureElement, EditPart elementEditPart) {
		if (FIGURE_ELEMENT_PRIMARY_SHAPE.equals(figureElement))
			return new EntityOvalFigure(false);
		if (FIGURE_ELEMENT_NAME.equals(figureElement)) {
			WrappingLabel label = (WrappingLabel) super.createFigureElement(element, 
					figureElement, elementEditPart);
			label.setTextJustification(PositionConstants.CENTER);
			label.setTextAlignment(PositionConstants.CENTER);
			label.setAlignment(PositionConstants.CENTER);
			label.setTextWrap(true);
			return label;
		}
		if (FIGURE_ELEMENT_STEREOTYPE.equals(figureElement)) {
			WrappingLabel label = (WrappingLabel) super.createFigureElement(element, 
					figureElement, elementEditPart);
			label.setTextJustification(PositionConstants.CENTER);
			label.setTextAlignment(PositionConstants.CENTER);
			label.setAlignment(PositionConstants.CENTER);
			return label;
		}
		if (FIGURE_ELEMENT_CONTENT_PANE.equals(figureElement)) {
			ActorCompartmentPaneFigure cp = new ActorCompartmentPaneFigure((ContainerEntityEditPart) elementEditPart);
			cp.setInsets(new Insets(20, 20, 0, 0));
			return cp;
		}
		return super.createFigureElement(element, figureElement, elementEditPart);
	}
	
	@Override
	protected void buildFigures(EditPart context, Element element,
			EditPart elementEditPart, Map<String, IFigure> figures) {
		
		final ContainerEntityEditPart actorEP = (ContainerEntityEditPart) elementEditPart;
		
		IFigure figPlate = figures.get(FIGURE_ELEMENT_PLATE);
		IFigure figName = figures.get(FIGURE_ELEMENT_NAME);
		IFigure figContentPane = figures.get(FIGURE_ELEMENT_CONTENT_PANE);
		IFigure figPrimary = figures.get(FIGURE_ELEMENT_PRIMARY_SHAPE);
		
		figures.put(FIGURE_ANCHORS, figPrimary);
		
		DockConstraint dc = new DockConstraint(DockConstraint.DOCK_FILL, 0, 0);
		//dc.setMargin(new Insets(20, 20, 0, 0));
		figPlate.add(figContentPane, dc);
		figPlate.add(figPrimary,
					new DockConstraint(DockConstraint.DOCK_FILL, 0, 0) {
			@Override
			protected Dimension getMaxSize(IFigure figure,
					Rectangle area, Rectangle clientArea) {
				CollapsableConstraint constraint = actorEP.getCollapsableConstraint();
				Size cs = constraint.getCollapsedSize();
				return new Dimension(cs.getWidth(), cs.getHeight());
			}
		});
		figPrimary.setLayoutManager(new DotNetLayout());
		figPrimary.add(figName, new DockConstraint(DockConstraint.DOCK_FILL, 0, 0));
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public View createView(IAdaptable semanticAdapter, View containerView,
			String semanticHint, int index, boolean persisted,
			PreferencesHint preferencesHint) {
		View view = null;
		
		if (semanticHint == null) {
			view = super.createView(semanticAdapter, containerView, semanticHint, index,
					persisted, preferencesHint);
			
			CollapsableConstraint sizes = ErmlStyleFactory.eINSTANCE.createCollapsableConstraint();
			Dimension size = ERML.Actor.getDefaultSize();
			sizes.setCollapsedSize(size.width, size.height);
			sizes.setExpandedSize(300, 300);
			
			view.getStyles().add(sizes);
			
			BasicCompartment compartment = NotationFactory.eINSTANCE.createBasicCompartment();
			compartment.setCollapsed(true);
			compartment.setType(ERML.ACTOR_COMPARTMENT_ID);
			
			ViewUtil.insertChildView(view, compartment, ViewUtil.APPEND, true);
		}
		
		return view;
	}
}
